/*
 * Copyright 2011-2012 Redia A/S
 * 
 * This file is part of Redias Library App for Android.
 *
 *  Redia Library App for Android is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  Redia Library App for Android is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *  
 *  You should have received a copy of the GNU General Public License
 *  along with Redia Library App for Android.  If not, see <http://www.gnu.org/licenses/>.
 */
package dk.redia.libraryapp;

import java.util.Map;

import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import dk.redia.lib.log.Log;
import dk.redia.lib.utils.AppApplication;
import dk.redia.lib.utils.AppConfiguration;
import dk.redia.lib.xmlrpc.XmlRpcClientResultListener;
import dk.redia.lib.xmlrpc.XmlRpcResultDumper;
import dk.redia.lib.xmlrpc.XmlRpcResultUtils;
import dk.redia.libraryapp.activityutils.LibraryAppActivity;
import dk.redia.libraryapp.model.Library;
import dk.redia.libraryapp.utils.ResourceUtils;
import dk.redia.libraryapp.xmlrpc.library.XmlRpcClient;

public class LibraryDetailsActivity extends LibraryAppActivity {

	private static final String logTag = "LibraryDetailsActivity";
	public static final String extraKeyLibrary = "library";

	private Library library;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.librarydetails);
	    
	    Parcelable p = getIntent().getExtras().getParcelable(LibraryDetailsActivity.extraKeyLibrary);	    
	    library = (Library)p;
	    
	    loading(true);
	    
	    TextView addressTextView2 = (TextView)findViewById(R.id.libraryDetailsAddress2TextView);
	    TextView addressTextView = (TextView)findViewById(R.id.libraryDetailsAddressTextView);
	    TextView nameTextView = (TextView)findViewById(R.id.libraryDetailsNameTextView);
	    TextView phoneTextView = (TextView)findViewById(R.id.libraryDetailsPhoneNumberTextView);
	    TextView faxTextView = (TextView)findViewById(R.id.libraryDetailsFaxNumberTextView);
	    	    
	    nameTextView.setText(library.getName());
	    addressTextView.setText(library.getStreet());
	    addressTextView2.setText(library.getCity());
	    if (library.getPhone().length()==0) {
	    	phoneTextView.setText("Nej");
	    } else {
	    	phoneTextView.setText(library.getPhone());
	    }
	    phoneTextView.setText(library.getPhone());
	    if (library.getFax().length()==0) {
	    	faxTextView.setText("Nej");
	    } else {
	    	faxTextView.setText(library.getFax());
	    }
	    
	    ImageView wideLogoImageView = (ImageView)findViewById(R.id.libraryDetailsWideLogoImageView);
	    wideLogoImageView.setImageResource(ResourceUtils.getWideLogoResourceId());
	    
	    loadOpeningHours();
	}

	public void onShowMapButtonClicked(View v) {
		Log.d(LibraryDetailsActivity.logTag, "Showing map");
		Intent intent = new Intent(this, LibraryMapActivity.class);
		intent.putExtra(LibraryMapActivity.EXTRA_KEY_ADDRESS, library.getStreet() + " " + library.getCity());
		intent.putExtra(LibraryMapActivity.EXTRA_KEY_TITLE, library.getName());
		startActivity(intent);
	}
	
	private void setLoadingError(String message) {
	    findViewById(R.id.libraryDetailsBottomTableLayout).setVisibility(View.GONE);
	    findViewById(R.id.libraryDetailsProgressBar).setVisibility(View.GONE);
	    findViewById(R.id.libraryDetailsErrorTextView).setVisibility(View.VISIBLE);
		((TextView)findViewById(R.id.libraryDetailsErrorTextView)).setText(message);
	}
	
	private void loading(boolean loading) {
	    findViewById(R.id.libraryDetailsErrorTextView).setVisibility(View.GONE);
	    findViewById(R.id.libraryDetailsBottomTableLayout).setVisibility(loading ? View.GONE : View.VISIBLE);
	    findViewById(R.id.libraryDetailsProgressBar).setVisibility(loading ? View.VISIBLE : View.GONE);
	}
		
	private String createOpeningHoursNoteString(Map<String, Object> m) {
		// FIXME This needs to be cleaned up, as it replicates the code
		// in createOpeningHoursString below
		StringBuilder r = new StringBuilder();
		if (m==null) {
			Log.e(logTag, "null map when creating opening hour string");
			return "Ingen noter";
		}
		if (m.containsKey("closed")) {
			Boolean closed = (Boolean)m.get("closed");
			if (closed) {
				return "Ingen noter";
			}
		}
		if (m.containsKey("schedule")) {
			Object[] schedule = XmlRpcResultUtils.unpackArray(m.get("schedule"));
			if (schedule!=null) {
				for (Object scheduleItemObj: schedule) {
					Map<String, Object> scheduleItem = (Map<String,Object>)scheduleItemObj;
					Log.d(logTag, "Found schedule item");
					// If this is not the first line, 
					// append a line break
					if (scheduleItem.containsKey("note")) {
						String note = (String)scheduleItem.get("note");
						if (note.length()>0) {
							if (scheduleItem.containsKey("open")) {
								r.append((String)scheduleItem.get("open"));
							} else {
								r.append("--");
							}
							r.append(" - ");
							if (scheduleItem.containsKey("close")) {
								r.append((String)scheduleItem.get("close"));
							} else {
								r.append("--");
							}

							r.append(":\n");
							
							r.append(note + "\n");
						} else {
							// No notes for this opening interval
//							r = new StringBuilder("Ingen noter");
						}
					}
				}
			} else {
				Log.e(logTag, "Schedule is not an array");
				r = new StringBuilder("-- - --");
			}
		}
		return r.toString();
	}
	
	private Spannable createOpeningHoursString(Map<String, Object> m) {
		SpannableStringBuilder r = new SpannableStringBuilder();
		if (m==null) {
			Log.e(logTag, "null map when creating opening hour string");
			return new SpannableString("Lukket");
		}
		if (m.containsKey("closed")) {
			Boolean closed = (Boolean)m.get("closed");
			if (closed) {
				return new SpannableString(getResources().getString(R.string.closedText));
			}
		}
		if (m.containsKey("schedule")) {
			Object[] schedule = XmlRpcResultUtils.unpackArray(m.get("schedule"));
			if (schedule!=null) {
				for (Object scheduleItemObj: schedule) {
					Map<String, Object> scheduleItem = (Map<String,Object>)scheduleItemObj;
					Log.d(logTag, "Found schedule item");
					// If this is not the first line, 
					// append a line break
					if (r.length()>0) {
						r.append("\n");
					}
					if (scheduleItem.containsKey("note")) {
						String note = (String)scheduleItem.get("note");
						if (note.length()>0) {
							r.append(Html.fromHtml("[<a href=\"#\">Note</a>]"));
						}
					}
					if (scheduleItem.containsKey("open")) {
						r.append((String)scheduleItem.get("open"));
					} else {
						r.append("--");
					}
					r.append(" - ");
					if (scheduleItem.containsKey("close")) {
						r.append((String)scheduleItem.get("close"));
					} else {
						r.append("--");
					}

				}
			} else {
				Log.e(logTag, "Schedule is not an array");
				r = new SpannableStringBuilder("-- - --");
			}
		}
		return r;
	}
	
	private void loadOpeningHours() {
		XmlRpcClient.getInstance().getOpeningHours(AppConfiguration.getInstance().getCustomerId(), AppConfiguration.getInstance().getApiKey(), new XmlRpcClientResultListener() {
			
			public void callFailed(String message) {
				loading(false);
				Log.e(LibraryDetailsActivity.logTag, "Failed to retrieve opening hours for library with id" + library.getId());
				setLoadingError(message);
			}
			
			public void callCompleted(Object resultObj) {
				XmlRpcResultDumper.dump(resultObj);
				loading(false);
				Map<String, Object> result = XmlRpcResultUtils.unpackStandardResult(resultObj);
				Boolean resultResult = false;
				String message = getResources().getString(R.string.libraryDetailsFailedToFetchOpeningHoursText);
				if (result != null && result.containsKey("result")) {
					resultResult = (Boolean)result.get("result");
				}  else {
					Log.d(LibraryDetailsActivity.logTag, "Failed to find result in response object");
				}
				if (resultResult) {
					Log.d(LibraryDetailsActivity.logTag, "Found opening hours");
					Object data = result.get("data");
					Object[] libraryOpeningHoursArr = XmlRpcResultUtils.unpackArray(data);
					if (libraryOpeningHoursArr == null) {
						// Report error and exit.
						Log.w(LibraryDetailsActivity.logTag, "Error unpacking opening hours.");
						setLoadingError("Error getting opening hours from server.");
						return;
					}
					Log.d(LibraryDetailsActivity.logTag, "Found opening hours for " + libraryOpeningHoursArr.length + " weeks");
					Map<String, Object> libraryOpeningHoursMapWeek0 = XmlRpcResultUtils.unpackStruct(libraryOpeningHoursArr[0]);
					if (libraryOpeningHoursMapWeek0 == null) {
						// Report error and exit.
						Log.w(LibraryDetailsActivity.logTag, "Error unpacking opening hours for week 0.");
						setLoadingError("Error getting opening hours from server.");
						return;
					}
					// Not currently used
					//Map<String, Object> libraryOpeningHoursMapWeek1 = XmlRpcResultUtils.unpackStruct(libraryOpeningHoursArr[0]);
					
					Log.d(LibraryDetailsActivity.logTag, "Looking for opening hours for library with id " + library.getId());
					Map<String, Object> libraryOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryOpeningHoursMapWeek0.get(library.getId()));
					if (libraryOpeningHoursMap == null) {
						// Report error and exit.
						Log.w(LibraryDetailsActivity.logTag, "Error unpacking libraryOpeningHoursMap.");
						setLoadingError("Error getting opening hours from server.");
						return;
					}
					if (libraryOpeningHoursMap.containsKey("open") != true) {
						Log.w(LibraryDetailsActivity.logTag, "Key \"open\" missing in libraryOpeningHoursMap.");
						setLoadingError("Error getting opening hours from server.");
						return;						
					}
					Boolean isOpen = (Boolean)libraryOpeningHoursMap.get("open");
					Map<String, Object> libraryDailyOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryOpeningHoursMap.get("days"));
					if (libraryDailyOpeningHoursMap == null) {
						Log.w(LibraryDetailsActivity.logTag, "Error unpacking libraryDailyOpeningHoursMap.");
						setLoadingError("Error getting opening hours from server.");
						return;
					}
					Map<String, Object> mondayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("mon"));
					Map<String, Object> tuesdayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("tue"));
					Map<String, Object> wednesdayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("wed"));
					Map<String, Object> thursdayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("thu"));
					Map<String, Object> fridayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("fri"));
					Map<String, Object> saturdayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("sat"));
					Map<String, Object> sundayOpeningHoursMap = XmlRpcResultUtils.unpackStruct(libraryDailyOpeningHoursMap.get("sun"));
					
					findViewById(R.id.libraryDetailsOpenTextView).setVisibility(isOpen ? View.VISIBLE : View.GONE);
					
					if (mondayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursMondayTextView));
						Spannable s = createOpeningHoursString(mondayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(mondayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for monday for library with id " + library.getId());
					}
					if (tuesdayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursTuesdayTextView));
						Spannable s = createOpeningHoursString(tuesdayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(tuesdayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for tuesday for library with id " + library.getId());
					}
					if (wednesdayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursWednesdayTextView));
						Spannable s = createOpeningHoursString(wednesdayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(wednesdayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for wednesday for library with id " + library.getId());
					}
					if (thursdayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursThursdayTextView));
						Spannable s = createOpeningHoursString(thursdayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(thursdayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for thursday for library with id " + library.getId());
					}
					if (fridayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursFridayTextView));
						Spannable s = createOpeningHoursString(fridayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(fridayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for friday for library with id " + library.getId());
					}
					if (saturdayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursSaturdayTextView));
						Spannable s = createOpeningHoursString(saturdayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(saturdayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for saturday for library with id " + library.getId());
					}
					if (sundayOpeningHoursMap!=null) {
						TextView tv = ((TextView)findViewById(R.id.libraryDetailsOpeningHoursSundayTextView));
						Spannable s = createOpeningHoursString(sundayOpeningHoursMap); 
						tv.setText(s);
						final String popupText = createOpeningHoursNoteString(sundayOpeningHoursMap);
						tv.setOnClickListener(new OnClickListener() {
							
							public void onClick(View v) {
								AppApplication.toast(popupText, Toast.LENGTH_SHORT);
							}
						});

					} else {
						Log.w(logTag, "No opening hours for sunday for library with id " + library.getId());
					}
										
				} else {
					Log.e(LibraryDetailsActivity.logTag, "Failed to loading opening hours");
					if (result != null && result.containsKey("message")) {
						message += " " + result.get("message");
					}
					Log.e(LibraryDetailsActivity.logTag, message);
					setLoadingError(message);
				}
			}
		});
	}

}
